<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-2">
<title>Design Philosophy Behind Motorola's MC68000 (2)</title></head><body>
<center>
<script type="text/javascript"><!--
	google_ad_client = "pub-0565437031849443";
	/* 728x90, Paulrsm */
	google_ad_slot = "7189181649";
	google_ad_width = 728;
	google_ad_height = 90;
	//-->
</script>
<script style="display: none;" type="text/javascript" src="dpbm68k2_pliki/show_ads.js">
</script>
<p>
</p></center>
<font size="4"><a href="http://www.easy68k.com/index.html">EASy68K Home</a>
</font>

<h1>Design Philosophy Behind Motorola's MC68000</h1>
<h2>Part 2: Data-movement, arithmetic, and logic instructions</h2>
<p>May 1983 &#169; BYTE Publications Inc</p>
<p>Thomas W. Starnes<br>Motorola Inc., Microprocessor Division<br>3501 Ed Bluestein Blvd.<br>Austin, TX 78721</p>
<p>Last month, in part 1, I discussed the design philosophy behind the
Motorola MC68000, a powerful 16-bit processor with multiple 32-bit
registers. This month I'll describe the data-movement, arithmetic, and
logic instructions of the MC68000. A thorough reading of the MC68000's
user's guide (available from many computer bookstores and Motorola
distributors) will give you all the details of each instruction's
operation, but a look at the general categories of instructions, a
discussion of why certain design decisions were made, and mention of
some special capabilities of the instructions will give you insight
into the power of this instruction set.</p>
<hr>
<p><b>Photo 1:</b> <i>The MC68000 microprocessor chip, which contains
more than 68,000 transistors, is 246 by 281 mils (6.24 by 7.14 mm) in
size. This photo shows the location of the major functions of the chip.
"Int. Log." stands for "Interrupt Logic"; "A0 Mux Control", for
"Microcode A0 Multiplexer Control"; and "FC Log.", for "Function Code
Logic." The labels "&#181;ROM" and "NROM" indicate two areas of microcode.
"Trap and Ill. Inst. PLA" stands for "Trap and Illegal Instruction
Programmable Logic Array"; "IRD Reg.", for "Instruction Register Decode
Register"; and "ALU Control", for "Arithmetic and Logic Unit Control."
The Data Execution Unit houses the main functions of the arithmetic and
logic unit, while the two Address Execution Units perform the
arithmetic associated with the calculation of an address.</i></p>
<img src="68000 Design Philosophy Behind 2_pliki/chip68k.jpg">
<hr>
<h3>Instruction Format and Addressing Modes</h3>
<p>Before I get into the instruction groups, let's first look at how
assembly-language instructions are written. Table 1 illustrates a
common instruction format and the choices that can be made within it.
First, of course, you can pick one of several microprocessor
instructions -- for example, an addition (ADD), comparison (CMP),
arithmetic shift left (ASL), or data move (MOV). If the instruction is
one that handles data, you can, with the MC68000, select one of three
data sizes: 8, 16, or 32 bits. This selection is made by following the
mnemonic with a period and either a "B", "W", or "L", for byte, word,
or long word; if no size is specified, the assembler will assume a
16-bit operation.</p>
<hr>
<p><b>Table 1:</b> <i>General format for MC68000 instructions.</i></p>
<pre> Instruction format is:
         mnemonic.size    source,destination

 Examples:
         ADD.L D1,D2
         MOVE.B #15,-1(A0)
         ADD D1,D2           (size assumed to be ".W")
         BGE LOOP1           (only one argument)
         RTS                 (no arguments)

 Explanations:
         mnemonic = instruction abbreviation (ADD, CMP, MULS, etc.)
         size (optional) = operand size:
                 .B means byte data (8 bits)
                 .W means word data (16 bits; default size)
                 .L means long word data (32 bits)
         source (optional) = source operand addressing mode
         destination (optional) = destination operand addressing mode
</pre>
<hr>
<p>On a data operation, you need to make one or two more decisions,
i.e., which addressing mode to use for the one or two operands the
instruction requires. (See the text box on data organization on page
354 for more details.) Typically, you can select one of 14 modes;
within most of these modes, one of eight address registers is selected.
On many operations, you need to select a second addressing mode; this
usually involves selection of one of eight data registers, but for the
data-movement instruction, any addressing mode can be selected.</p>
<p>All MC68000 instructions are fully defined with 16 bits of <i>op code</i>.
(Op code is short for operation code; it is the pattern of bits that a
microprocessor interprets as a specific machine-language instruction
executable by it.) Depending on the instruction or the addressing
mode(s) selected, additional 16-bit extension words may follow the op
code. These extension words provide additional addressing information
and may make the total instruction length as long as 10 bytes. Because
the instruction is always lengthened by multiples of 16 bits, you can
ensure that instructions always begin on even-byte boundaries; because
of the way the MC68000 fetches 16-bit quantities from memory, this
placement of instructions increases the speed of program execution.</p>
<p>By far, the most common operation in any processor application is
the movement of data. Other microprocessors move data with LOAD, STORE,
PUSH, PULL, POP, and input/output (I/O) instructions. When you boil it
all down, each instruction simply moves data from one location to
another. So why not call them all MOVE? Simplicity of expression is a
fundamental theme throughout the MC68000's instruction set: all similar
operations should perform similarly in a number of respects. For
example, if you can use an ADD operation with two 32-bit quantities,
you should be able to use an add-with-carry operation with two 32-bit
quantities. If you can select from 14 addressing modes to use an ADD
operation, you should be able to select from 14 addressing modes to use
SUB (subtract). If certain status register codes are modified to
reflect the results of an ADD, the same codes should also be modified
when a SUB or NEG (negate) instruction is performed.</p>
<h3>Varieties of MOVEs</h3>
<p>With this philosophy in mind, all of the old LOAD, STORE, PUSH,
PULL, POP, and I/O instructions from other microprocessors were rolled
into one very powerful and flexible MOVE instruction in the MC68000.
Let's look at just what this one instruction can do.</p>
<p>The MOVE instruction can move 8-, 16-, or 32-bit data from
practically any location to practically any other. And a wide selection
of addressing modes and registers for both the source and the
destination should cover about any way you want to find the operands.
Table 2 lists the different combinations of addressing modes available
on both the MC68000 and the Intel 8086 families. Let's look at what
some of the MC68000 addressing-mode combinations allow you to do.</p>
<hr>
<p><b>Table 2:</b> <i>Addressing modes available to the Motorola
MC68000 and the Intel 8086. The information at the intersection of a
row and a column indicates the availability of that source/destination
addressing-mode combination for each microprocessor.</i></p>
<pre>            destination  Dn  An  (An)  (An)+  -(An)  d16(An)  d8(An,Xn)  Abs.W  Abs.L
            -------------------------------------------------------------------------
             #options    8   8    8      8      8       8        128      N/A    N/A
 ====================================================================================
 source    | #options |
 Dn        |     8    |  MI  MI   MI     M      M       MI        MI      MI      M
 An        |     8    |  MI  MI   MI     M      M       MI        MI      MI      M
 (An)      |     8    |  MI  MI   MI     M      M       M         M       M       M
 (An)+     |     8    |  M   M    M      M      M       M         M       M       M
 -(An)     |     8    |  M   M    M      M      M       M         M       M       M
 d16(An)   |     8    |  MI  MI   M      M      M       M         M       M       M
 d8(An,Xn  |   128    |  MI  MI   M      M      M       M         M       M       M
 Abs.W     |   N/A    |  MI  MI   M      M      M       M         M       M       M
 Abs.L     |   N/A    |  M   M    M      M      M       M         M       M       M
 d16(PC)   |     1    |  M   M    M      M      M       M         M       M       M
 d8(PC,Xn) |    16    |  M   M    M      M      M       M         M       M       M
 Immediate |     1    |  M   M    M      M      M       M         M       M       M</pre>
<p>Notes:</p>
<ol>
<li>"M" means this combination available on the Motorola MC68000.<br> "I" means a comparable combination available on the Intel 8086 family.
</li><li>"#options" refers to the number of different ways an
addressing mode can be used in the MC68000 due to the availability of
multiple registers that can be used; for example, the "d8(An,Xn)"
option can use 8 An registers and 16 Xn registers for a total of 128
combinations. "N/A" means "not applicable."
</li><li>Most of the source and destination addressing modes are
explaned in the text box "Data Organization and Addressing Modes," page
354. "An" and "Dn" are register addressing modes. "Abs.W" and "Abs.L"
are word-address and long-word-address forms of absolute addressing.
</li></ol>
<hr>
<p>Certainly, you can copy data between registers, but you can also
copy data to or from a register to memory using any of the
memory-addressing modes. Most microprocessors allow the programmer to
transfer data on the top of a stack to or from a register only. What if
the data is really needed elsewhere in memory? You must run a second
instruction to make the second move and use a register for a temporary
holding space. The MC68000 allows you to move top-of-stack data to or
from any register, another stack, a queue, any memory location, or any
I/O location, all in one smooth motion. And why shouldn't you be able
to? An added advantage of the MC68000 comes from its ability to use any
one of the eight address registers as a stack pointer; this allows you
to build as many as eight different stacks without having to swap out
registers.</p>
<p>You can also do direct memory-to-memory moves. There are 10
different memory-addressing modes to select from for the source operand
and seven for the destination. Also, keep in mind that each addressing
mode can use any of the eight address registers, further increasing the
versatility of these move instructions. (Actually, in one mode, you
have 16 registers to choose from -- eight address and eight data
registers.)</p>
<p>Just how many different ways are there to move general data in the
MC68000? When you couple all of the combinations allowed with the
selection of registers available, there are 34,888 different ways, and
each one can be used for 8-, 16-, or 32-bit data. That ought to solve
most programmers' data-shuffling problems!</p>
<p>The remaining data-movement instructions include SWAP, for instance,
which exchanges the contents of any two data and/or address registers.
You can read or modify the status register codes with a MOVE SR (Status
Register) instruction.</p>
<p>The MC68000 was designed to interface directly to the MC6800 line of
8-bit peripherals so that all the existing peripheral circuits could
easily be used on the MC68000. (Many of the 8-bit peripherals provide
very useful functions that would need to be included in a 16-bit
system.) To bring the best of the 8-bit peripheral world into the
universe of 16-bit software, designers included a special MOVEP (Move
Peripheral) instruction in the MC68000. Here's how and why it works.</p>
<p>Frequently, you must set up registers to ready a peripheral for
operation. You need to connect an 8-bit peripheral to either the upper
or lower half of the 16-bit-wide data bus. This means that the
registers connected to a peripheral appear within the MC68000 memory
address space as successive-even or successive-odd addresses. The MOVEP
instruction will move either 16 or 32 bits of a given data register out
to memory in 8-bit chunks, starting at a given location (see figure 1);
addresses for each successive byte are incremented by two, not by the
one that the normal MOVE uses. This allows the 2 or 4 bytes being
transferred to be loaded into the proper peripheral port addresses.
Thus, you can load as many as four 8-bit registers in one simple
instruction. The MOVEP instruction is bidirectional, so that the
registers can be either loaded or read.</p>
<hr>
<p><b>Figure 1:</b> <i>Moving data from a 32-bit register to memory
using the MOVEP instruction. Bytes from the register are stored in
every other memory byte. The instruction takes 24 clock cycles to
execute.</i></p>
<pre>                       LONG TRANSFER TO/FROM AN EVEN ADDRESS.

                  31       24 23       16 15        8 7         0
                  -----------------------------------------------
 REGISTER:       | HIGH-ORDER| MID-UPPER | MID-LOWER | LOW-ORDER |
                  -----------------------------------------------


         BYTE                                                      BYTE
         ADDRESS  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0  ADDRESS
                  -----------------------------------------------
 MEMORY       2N |      HIGH-ORDER       |                       | 2N+1
                  -----------------------------------------------
            2N+2 |       MID-UPPER       |                       | 2N+3
                  -----------------------------------------------
            2N+4 |       MID-LOWER       |                       | 2N+5
                  -----------------------------------------------
            2N+6 |       LOW-ORDER       |                       | 2N+7
                  -----------------------------------------------</pre>
<hr>
<p>Two special types of the MOVE instruction are the MOVEQ (Move Quick)
and the MOVEM (Move Multiple Register). Often a register is used as a
counter or a constant, with values that are typically rather small. The
MOVEQ instruction makes it fast and easy to initialize a register to
such values. MOVEQ will take any signed 8-bit immediate value between
-128 and 127, extend its sign bit so that it will be correctly
interpreted as a 32-bit number, and load it into one of the data
registers. The op code for MOVEQ includes the 8-bit immediate value;
this means the microprocessor can perform the operation very quickly.
Because the small immediate value is part of the MOVEQ op code itself,
the instruction is classified as a separate addressing mode of the
MC68000 called the "quick immediate" addressing mode.</p>
<p>It is common in machine-language programming to have to save the
contents of various on-chip registers, use the registers for some other
purpose, and then restore their former contents. This happens when you
are beginning or ending a subroutine, executing an interrupt handler,
changing tasks, or calling the operating system. The MC68000 has a very
handy instruction that makes this a fast, efficient operation. The
MOVEM instruction will take any combination (or all) of the 16 data and
address registers and move them either to or from memory in an
organized manner. These registers can be transferred to or from any
stack or to a specific location in memory. They are put in memory and
taken from memory in reverse order to ensure that each register
receives its proper contents. An option of the MOVEM instruction is
that either the lower 16 bits of the registers or the entire 32-bit
registers can be transferred. An example of this instruction is:</p>
<pre>     MOVEM.L D0/D4-D7/A4/A5,40(A6)</pre>
<p>which would save the registers as shown in figure 2. (The
instruction will save registers D0, D4 through D7, A4, and A5 into
memory starting at the location pointed to by the value in register A6
plus the value 28 hexadecimal.) The list of registers to be transferred
is compactly encoded in a 16-bit value that follows the MOVEM op-code
word -- an "on" bit indicates the associated register is to be
transferred. Not only is the MOVEM instruction both compact and useful,
it is also as fast as possible for the number of bytes of information
that must be transferred.</p>
<hr>
<p><b>Figure 2:</b> <i>Pushing multiple registers to memory with the
MOVEM instruction. This instruction offers a very fast way to store
selected registers in memory and, later, restore them properly. This
figure shows the storage of registers D0, D4 through D7, A4, and A5 to
location 91C028 hexadecimal. The instruction itself is MOVEM.L
D0/D4-D7/A4/A5,40(A6). (Remember that 40 decimal equals 28
hexadecimal.) The instruction takes 58 clock cycles to execute.</i></p>
<pre>                -----------------
 REGISTER  A6  | 0 0 9 1 C 0 0 0 |
                -----------------

                                   ADDRESS        MEMORY
   CONTENTS OF A6     91C000       (HEXADECIMAL)  (ORGANIZED
 + DISPLACEMENT       +   28                      AS WORDS)
   ----------------   ------                      ---------
   STARTING ADDRESS   91C028 -----------&gt; 91C028 | D0-HIGH |
                                                 |-       -|
                                              2A | D0-LOW  |
                                                 |---------|
                                              2C | D4-HIGH |
                                                 |-       -|
                                              2E | D4-LOW  |
                                                 |---------|
                                              30 | D5-HIGH |
                                                 |-       -|
                                              32 | D5-LOW  |
                                                 |---------|
                                              34 | D6-HIGH |
                                                 |-       -|
                                              36 | D6-LOW  |
                                                 |---------|
                                              38 | D7-HIGH |
                                                 |-       -|
                                              3A | D7-LOW  |
                                                 |---------|
                                              3C | A4-HIGH |
                                                 |-       -|
                                              3E | A4-LOW  |
                                                 |---------|
                                              40 | A5-HIGH |
                                                 |-       -|
                                          91C042 | A5-LOW  |
                                                  --------- </pre>
<hr>
<h3>Orthogonality</h3>
<p>Arithmetic operations are key instructions in a microprocessor
because they tend to be the ones that do the bulk of the work. The
arithmetic and logic instructions allow programmers to write code
exactly as they desire without having to rearrange data, gather more
data, or do things in an unnatural order. As with so many other
characteristics of the MC68000, the design of the arithmetic and logic
instructions is very orthogonal -- more so than for any previous
microprocessor. Orthogonality can be defined as the ability of any
allowed operation to use any resource in any way that any other
operation may.</p>
<p>The arithmetic and logic instructions are very similar in the way
they function, the way the condition codes are affected as a result,
and the selection of addressing modes, registers, and operands
available to them. The advantage of this is that, when coding, the
programmer has only one uniform set of rules to remember. Older
microprocessor designs forced programmers to have different sets of
rules for even similar instructions, which decreased programmers'
productivity by forcing them to recall and use correctly large amounts
of essentially arbitrary information.</p>
<p>All of the dual-operand arithmetic instructions are true
"one-and-a-half" address operations (i.e., one operand can be specified
as a memory address, but the other must be an internal register -- the
result overwrites one operand). Thus, you can add any register to any
register, a constant to any register, the top of a stack to any
register, a value buried in a stack to any register, a table entry to
any register, an input from an I/O device to any register, or any
memory location to any register. Or, because the order may be reversed,
you can add any register to any of the same (except that you can't add
to a constant, and you can't use the program-counter relative
addressing mode to specify a destination). Also, remember that any of
these instructions can occur with 8-, 16-, or 32-bit data.</p>
<h3>Arithmetic Instructions</h3>
<p>Let's look at the types of arithmetic instructions that are
available. Add (ADD), subtract (SUB), and compare (CMP) instructions
are general two-operand instructions. ADDX and SUBX are used to work on
numbers longer than 32 bits (the X condition bit in the MC68000
performs a function similar to the one the carry bit performs in most
microprocessors). Two multiply and divide instructions are available:
signed (MULS and DIVS) for single-precision instructions and unsigned
(MULU and DIVU) for multiple-precision instructions.</p>
<p>The negate (NEG) and clear (CLR) instructions require only a single
operand, and you can use a NEGX to negate multiple-precision values. To
blend mixed sizes of data, the MC68000 provides a sign-extend
instruction (EXT), while a TST (test) instruction is used to check for
positive, negative, or zero conditions. A special instruction, the
indivisible test-and-set (TAS), provides software synchronization in
multimicroprocessor operations.</p>
<p>One variation on the ADD instruction enables the MC68000 to overcome
a common limitation of other microprocessors. The normal
"one-and-a-half" address design of most processors makes it difficult
to use constant (immediate) values with anything but registers. The
MC68000 overcomes this with the ADDI instruction, which allows a byte,
word, or long-word immediate value to also be added to an operand in
memory using any legal destination-memory addressing mode.</p>
<p>The MC68000 has no increment or decrement instructions. Why?
Remember, the idea is to treat all similar instructions the same. An
increment instruction adds 1 to a quantity and is often used to step to
the next element in a table of byte-wide values. But the MC68000
programmer will often be manipulating 16- and 32-bit data, which
require increments of 2 and 4, respectively, to the table address. The
design team wanted to generalize the increment and decrement
instructions to make them useful with all data sizes yet still retain
the speed associated with an instruction that does not have to fetch an
immediate argument. To solve these problems, and then some, the
designers gave the MC68000 "add quick" (ADDQ) and "subtract quick"
(SUBQ) instructions, which allow any number from 1 to 8 to be added to
or subtracted from any register or any memory location. The
instructions accomplish this in the shortest possible time by using 3
bits within the 16-bit op code to hold the increment or decrement
amount (in this scheme, the bits 000 indicate an operand value of 8,
not 0). Then, not only can you quickly and easily change an address
pointer by 1, 2, or 4 for 8-, 16-, or 32-bit data, but you can also
change counters by 3, 5, 6, 7, or 8. And the effect is identical to
that using the standard ADDI instruction -- even the status register
codes are all the same.</p>
<p>Some odds and ends of arithmetic instructions include sign-extend
(EXT), clear (CLR), and test (TST) instructions. Since three different
sizes of data can be used in the MC68000, there should be a convenient
way of changing size. If you want to move only part of a datum (for
example, the bottom 16 bits of a 32-bit register), you need only use a
MOVE instruction of the proper data size. If, however, you want to
convert a datum to a larger-sized two's-complement value (for example,
making a 16-bit value into a 32-bit expression), you need a special
instruction. The EXT instruction will take an 8-bit or a 16-bit datum
and duplicate its uppermost bit position through the higher portions of
any data register in order to convert the datum to 16 or 32 bits wide,
respectively. CLR simply loads a set of 0s into the destination. TST
sets the negative and zero condition bits (discussed in the next
section) according to the nature of the given operand.</p>
<h3>Status Register Codes and Multiple-Precision Arithmetic</h3>
<p>What if you are dealing with binary integers that require more than
32 bits for expression? Say you want to add two 128-bit (16-byte)
numbers. If both of these numbers were in the MC68000 registers, all
eight data registers would be in use. More likely, the two values would
be in 16 consecutive bytes of memory, starting with the most
significant byte of data. The normal procedure to add two such numbers
is to add the two least significant bytes, remember the carry, go to
the previous bytes and add them, remember the carry, and so on. This
sequence of operations is handled neatly in the MC68000 by the
predecrement address-register deferred mode, which uses the notation
"-(An)". Use two address registers to point to the byte just past each
operand. Each execution of an ADDX -(Am),-(An) instruction will
decrement the values in the Am and An registers (m and n stand for
numbers between 0 and 7), then add the two numbers pointed to by those
registers. By putting this single instruction in a loop, you can
quickly create the code needed to operate on multiple-precision numbers.</p>
<p>Let's detour for a second to discuss the status register of the
M68000 (see figure 3). It contains the standard carry (C), overflow
(V), zero (Z), and negative (N) bits found in other microprocessors. It
also has a status-register bit not found on other microprocessors, the
X (or extend) bit. This bit was created to eliminate confusion caused
by traditional overuse of the carry bit.</p>
<hr>
<p><b>Figure 3:</b> <i>The bits of the MC68000 status register (SR).</i></p>
<pre>                          MC68000 STATUS REGISTER

                        SYSTEM BYTE       USER BYTE
                     ________|_______   ______|______
                    /                \ /             \
                    15  13    10     8 7     4       0
                    ----------------------------------
                   |T| |S| | |I2|I1|I0| | | |X|N|Z|V|C|
                    ----------------------------------
                    |   |     \______/       | | | | |
     TRACE MODE ----    |        |           | | | | |
    SUPERVISORY --------         |           | | | | |
 INTERRUPT MASK -----------------            | | | | |
         EXTEND -----------------------------  | | | |
       NEGATIVE -------------------------------  | | |
           ZERO ---------------------------------  | |
       OVERFLOW -----------------------------------  |
          CARRY -------------------------------------</pre>
<hr>
<p>To explain the extend bit, I should describe the carry bit. In most
microprocessors, the carry bit is overused. It is changed by (among
other things) an addition instruction, but it is used in two different
ways. Sometimes it is used in a later addition, such as in
multiple-precision additions; sometimes a program tests the bit and
branches according to the carry bit's state. So programmers use the
carry bit for two different purposes: for extended-precision arithmetic
and for program control.</p>
<p>The MC68000 has a bit for each purpose. Both the carry and the
extend bits are changed according to the results of an addition
instruction. However, the carry bit is used by the microprocessor
during testing for program control purposes, while the extend bit is
used as an input for multiple-precision arithmetic operations. For ADD,
SUB, NEG, and specified shift and rotate instructions, both the carry
and extend bits are updated. Other instructions -- MOVE, AND, OR, TST,
CLR, MUL, and DIV -- change only the carry bit. This design helps
prevent inadvertent changes to either bit.</p>
<p>Because of the extend bit, the familiar "add with carry" operation
in the MC68000 becomes ADDX or "add with extend bit." Look at why this
is important. Once you start a multiple-precision arithmetic operation
and get a partial result, the integrity of the extend bit will be
maintained even if you have to suspend the addition to do some data
movement with the MOVE instruction. Programming becomes easier because
you don't have to save the status register codes when interrupting a
multiple-precision operation.</p>
<p>I should mention one other thing about multiple-precision
arithmetic. When you have finished the multiple-precision operation,
what does the negative bit mean? It correctly indicates that the result
was positive or negative. In most microprocessors, though, the zero bit
indicates only that the most significant portion of the result is 0,
not that the entire result is 0. The multiple-precision arithmetic
instructions in the MC68000 are designed so that the zero bit will
accurately depict the status of the entire result. This is done by
allowing multiple-precision instructions to reset the zero bit
(denoting a nonzero result) but not to set it (denoting a zero result).
With this scheme, the programmer's only responsibility is to set the
zero bit before beginning the multiple-precision operation.</p>
<p>One final issue can come up in the middle of arithmetic operations,
and the MC68000's handling of the problem illustrates another
fundamental difference between it and so many other microprocessors.
How many times have you interrupted a series of arithmetic operations
to modify some memory pointers and later discovered that your completed
arithmetic operation gave a wrong result because you inadvertently
modified certain status register code bits? When you get right down to
it, when you add 12 to a memory address, who cares if a carry was
generated or if the result was negative? In fact, the negative bit has
no meaning in relation to addresses. We as programmers are hurt by the
senseless changing of status register code bits when address-related
operations are run. Why don't we leave these bits alone when changing
memory addresses?</p>
<p>As you can imagine, the designers of the MC68000 have addressed this
problem. One of the primary distinctions between the data and address
registers in the MC68000 is that instructions with an address register
as the destination do not modify the status register code bits. They
are not changed by moving a new pointer value into an address register,
incrementing or decrementing an address register, or by adding any
value to an address register. This means that you should never run into
a problem with memory-pointer modifications affecting your ongoing data
arithmetic operations.</p>
<p>Another interesting note is that all operations to any address
register affect the entire address register. Because all MC68000
addresses are 32 bits wide, any operations with an address register as
destination must perform in a way that keeps the result valid as a
32-bit address. One solution, to require all inputs to address-register
operations to be full 32-bit quantities, would be wasteful of memory
space. So either word (16-bit) or long-word (32-bit) operations may
take place in any of the address registers A0 through A7. If a word
operation is performed, the 16-bit quantity is first sign-extended to
32 bits before it is used.</p>
<hr>
<h3>Data Organization and Addressing Modes</h3>
<p>Motorola designed the MC68000 to offer a versatile set of data sizes
and addressing modes for the assembly-language programmer. To
understand fully the power of this machine, you must first understand
how the MC68000 organizes and moves data.</p>
<p>Although the MC68000 "sees" its memory space as a collection of
8-bit bytes, it works on several different data sizes. It can address
memory in the following sizes: byte (8 bits), word (16 bits), and long
word (32 bits). In addition, it can manipulate individual bits -- a bit
is specified by the byte it is in and its bit number (between 0 and 7)
within the byte.</p>
<p>The MC68000 has a definite preference for addressing 16- and 32-bit
quantities that start at even addresses. In particular, it was designed
to access quickly 16-bit quantities that start on an even address. Even
though this speed comes at the expense of words and long words that
begin at odd addresses (which would take two, not one, fetch operations
to be accessed), this is not a serious disadvantage. MC68000 op codes
are always 16 bits wide, and any arguments the MC68000 requires are
always stored as one or more 16-bit words (even if the argument is only
a byte quantity). Because of this, code that starts on an even-byte
boundary will stay on an even-byte boundary and thus will be accessed
at the fastest rate possible.</p>
<p>The MC68000 register set (see the figure) indicates the
microprocessor's commitment to long-word data: even though this is a
16-bit machine, all the internal registers are 32 bits wide. The dotted
lines in the data registers denote those registers' ability to handle
8-, 16-, or 32-bit-wide data. The address registers can handle either
16- or 32-bit-wide data.</p>
<pre>  31                   16 15        8 7         0
  -----------------------------------------------
 |                       |           |           | D0
  -----------------------------------------------
 |                       |           |           | D1
  -----------------------------------------------
 |                       |           |           | D2
  -----------------------------------------------       EIGHT
 |                       |           |           | D3   DATA
  -----------------------------------------------       REGISTERS
 |                       |           |           | D4
  -----------------------------------------------
 |                       |           |           | D5
  -----------------------------------------------
 |                       |           |           | D6
  -----------------------------------------------
 |                       |           |           | D7
  -----------------------------------------------
  31                   16 15        8 7         0
  -----------------------------------------------
 |                       |           |           | A0
  -----------------------------------------------
 |                       |           |           | A1
  -----------------------------------------------
 |                       |           |           | A2
  -----------------------------------------------       SEVEN
 |                       |           |           | A3   ADDRESS
  -----------------------------------------------       REGISTERS
 |                       |           |           | A4
  -----------------------------------------------
 |                       |           |           | A5
  -----------------------------------------------
 |                       |           |           | A6
  -----------------------------------------------

  -----------------------------------------------
 |                USER STACK POINTER             |      TWO
  -----------------------------------------------  A7   STACK POINTERS
 |          SUPERVISOR STACK POINTER             |
  -----------------------------------------------
  31                                            9
  -----------------------------------------------
 |                       |           |           |      PROGRAM COUNTER
  -----------------------------------------------

                          15        8 7         0
                          -----------------------
                         |SYSTEM BYTE| USER BYTE |      STATUS REGISTER
                          -----------------------</pre>
<p>The MC68000 supports six major addressing modes; although I will not
go into the variations available in each mode, a short description of
each will show you the basic ways the micro processor can get its
operands.</p>
<ul>
<li>Inherent addressing: the instruction itself tells the
microprocessor where to get its operand. An example of this is RTS,
return from subroutine, which gets the return address from the stack.
</li><li>Register addressing: the operand is a data or address
register. An example is MOVE D1,D2, which moves the contents of data
register D1 to data register D2.
</li><li>Immediate addressing: the operand is specified as part of the
instruction. An example is MOVE #3,D2, which moves the value 3 into
data register D2.
</li><li>Absolute addressing: the operand is specified by a 16- or
32-bit address that is appended to the instruction. An example is MOVE
$3F01,D2, which moves the contents of the word at address 3F01
hexadecimal into data register D2. This is also called <i>direct addressing</i> because the operand address is being directly supplied.
</li><li>Register-deferred addressing: this mode has a lot of
variations. Since these modes get rather complicated, I'll speak of
them in terms of what the <i>effective address</i> is -- that is, what memory location will be used to supply the source or destination operand. The simple <i>address-register deferred mode</i>
makes not the register but the contents of the register the effective
address. Because the register contents is itself the address of the
given operand, this addressing mode is often called <i>indirect addressing</i>
-- the register indirectly supplies the effective address. Suppose that
register A1 contains the value 100 and that the word at address 100
contains 12D hexadecimal. Then the instruction MOVE (A1),D2 will put
the value 12D hexadecimal into data register D2. The notation "(An)"
denotes address-register-deferred (or indirect) addressing using data
register An.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Two related variations on address register deferred are called <i>address-register deferred with predecrement</i> and <i>address-register deferred with postincrement</i>;
they have notations of "-(An)" and "(An)+", respectively. In the
predecrement variation, the address register An is decremented before
its contents is used as the effective address; in the postincrement
variation, the contents of the address register is used as the
effective address, then the register is incremented. These modes are
often used in loops for repetitive operations on sequential areas of
memory; they usually replace an explicit increment or decrement
instruction, thus providing more compact, faster code. The incremental
or decremental amount will be 1, 2, or 4 depending on whether the
operand is a byte, word, or long word.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Another variation is called <i>address-register deferred with displacement</i>;
in this mode (denoted "d16(An)"), the effective address is the contents
of address register An plus the signed 16-bit value d16. Suppose
address register A1 contains the value C100 hexadecimal and the word at
address C25E hexadecimal contains 0. Then the instruction MOVE
$15E(A1),D2 moves the value 0 into data register D2. (The effective
address, C25E hexadecimal, is the sum of the displacement 15E
hexadecimal and the contents of register A1, C100 hexadecimal.)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The variation called <i>address-register deferred with index and displacement</i>
(denoted "d8(An,Xn)") limits the displacement to an 8-bit signed number
but makes the effective address the sum of three numbers: the
displacement, the contents of the address register An, and the contents
of an index register Xn, where the index register can be any of the
address or data registers. The extra register is added into the
effective address calculation to allow the same instruction to point to
the base of a table (using d8 and An) and, during execution, to refer
to different nearby memory locations by putting different values into
the index register Xn. The word "index" in the addressing mode name
refers to the commonplace use of the index register to index into an
array of numbers stored sequentially; in such a case, the value in the
index register equals the subscript of the array element desired. Given
the example directly above (register A1 contains C100 hexadecimal, word
C25E hexadecimal contains 0) and the information that data register D6
contains is the value 100 hexadecimal, the instruction MOVE
$5E(A1,D6),D2 moves the same value (0) to data register D2 just as the
instruction MOVE $15E(A1),D2 would. In both cases, the effective
address is C25E hexadecimal.
</li><li>Program-counter relative addressing: this mode has two
variations, "d16 (PC)" and "d8 (PC,Xn)"; these are similar to the two
forms of address-register deferred addressing described above. It is
different in two ways: first, it uses the program counter (PC) instead
of an address register; second, you cannot use this mode to specify a
destination operand. The main advantage of this mode is that it allows
you to write position-independent code. Because the program counter
contains the address of the next instruction after the one currently
executing, its use allows the current instruction to refer to data (or
program locations for branches) relative to the instruction itself. The
MC68000 designers included the restriction against using this mode for
a destination operand to protect a program with errors from
inadvertently destroying itself. In addition, this restriction prevents
programmers from writing self-modifying code, a dangerous practice that
programmers occasionally try to increase program performance.
</li></ul>
<hr>
<h3>Processor Speed</h3>
<p>How fast does the MC68000 execute instructions? Because of the
consistency of the microprocessor, the answer for addition instructions
will serve as a guide for all arithmetic and logic instructions. A
prefetching mechanism in the MC68000 keeps decoded instructions waiting
to be executed. So while the timing information given refers only to
the time it takes to pass through the adder, recall that the prefetcher
will have fetched the next op code while the current op code is being
executed.</p>
<p>The minimum time it takes the MC68000 microprocessor to access
memory (to read or write) is 4 clock cycles. With a clock frequency of
8 MHz (the frequency used in the standard MC68000 microprocessor), this
bus cycle will take 500 ns (nanoseconds). (All subsequent timings will
be given in clock cycles, which is a meaningful measurement for all the
MC68000-family microprocessors, regardless of the speed of their system
clocks -- 8, 10, or 12.5 MHz.) Every instruction will take at least 4
clock cycles to complete because this is the time it takes to fetch the
next op code.</p>
<p>The MC68000 has only one 16-bit arithmetic and logic unit (ALU) for
data operations. Therefore, 8- or 16-bit operations can be performed in
a single pass through this unit; this takes 4 clock cycles. A 32-bit
operation will require a second pass. Memory-addressing modes increase
the time needed for an operation because the microprocessor requires
more time to calculate the addresses, and a bus cycle is required for
each 16 bits of addressing information or actual data that needs to be
transferred. An indexed addressing mode, or anything with a
displacement, for instance, will require 1 additional bus cycle for the
address extension word and another to get the data (2 if the data is a
long word); add about 8 more clock cycles (12 if the data is a long
word) to the execution time of a given instruction that uses this mode.
Some sample worst-case clock timings for various addition instructions
are given in table 3.</p>
<hr>
<p><b>Table 3:</b> <i>Examples of MC68000 addition instructions. The clock times given are worst-case times for the instruction.</i></p>
<pre> Instruction             Operation

 ADD.B D6,D2             adds the lower 8 bits of D6 to D2
                         (takes 4 clock cycles)

 ADD.L 52(A1,D7.W),D6    the effective address is the sum of the
                         constant 52, the contents of register
                         A1, and the lower 16 bits of register
                         D7; the long word at the effective
                         address is added to the contents of
                         register D6 (20 clock cycles)

 ADD.W D3,(A7)           adds the lower 16 bits of D3 to the
                         element on top of stack pointed to by A7
                         (12 clock cycles)

 ADDI.L #$400,D1         adds 400 hexadecimal to the 32-bit
                         contents of D1 (16 clock cycles)

 ADDI.B #$A9,$30B(A6)    the effective destination address is the
                         sum of the 30B hexadecimal and the
                         contents of register A6; A9 hexadecimal
                         is added to the byte at the effective
                         address (20 clock cycles)

 ADDA.W -(A5),A2         decrement register A5 by 2, then add the
                         word pointed to by register A5 to
                         register A2 (14 clock cycles)

 ADDA.W #100,A5          add the value 100 to the contents of
                         register A5 (12 clock cycles)

 ADDQ.W #1,(A4)+         add 1 to the word pointed to by register
                         A4, then increment register A4 by 2
                         (12 clock cycles)

 ADDQ.B #3,D7            add 3 to the contents of register D7
                         (4 clock cycles)

 ADDX.L -(A2),-(A5)      after decrementing both registers A2 and
                         A5 by 4, add together the X bit and the
                         two long words pointed to by A2 and A5
                         (30 clock cycles)</pre>
<hr>
<p>Like the ADD instruction, other MC68000 arithmetic instructions come
in several forms. The subtract instructions have forms analogous to the
add instructions -- SUB, SUBA, SUBI, SUBQ, and SUBX. Instructions for
compare operations that are all similar (CMP, CMPA, CMPI) perform the
subtractions without storing a result (the net effect is to set the
appropriate status register bits). A memory-compare instruction (CMPM)
allows two strings of binary integers in memory to be compared by
sequencing through them to higher memory. Two versions of the
single-operand negate instruction, NEG and NEGX, ignore and include,
respectively, the state of the X bit.</p>
<h3>Multiplication and Division</h3>
<p>Two versions of multiply and divide instructions make fast work of
more complex arithmetic. The two versions are unsigned (MULU and DIVU)
and signed (MULS and DIVS) instructions; these versions interpret their
operands as one's-complement and two's-complement numbers,
respectively. All of these instructions can include immediate values as
the multiplier or divisor so that variables can be operated on by
constants.</p>
<p>The multiply instructions take two 16-bit operands (one from any
memory location by any addressing mode or any data register, and the
other from the lower 16 bits of any data register), multiply them, and
place the resulting product into the full 32 bits of the same data
register. The divide instructions take the dividend from any 32-bit
data register and divide it by a 16-bit divisor, which may come from
memory using any addressing mode or any data register. The quotient is
placed in the lower 16 bits of the same 32-bit data register, while the
16-bit remainder is placed in the upper 16 bits of the same register.</p>
<p>The divide instruction has two characteristics that may be
undesirable and so are specially handled. All of us remember from high
school and college that there just isn't any good way to divide by
zero. The result is infinite if it's defined at all. Well, Motorola's
designers didn't think they knew any better than the mathematicians, so
if a zero divisor is detected, the divide instructions do not execute,
and a special "trap" procedure is entered. Since the trap operation
will be covered in part 3 of this article, let's just say that a
"zero-divide trap" specially calls the operating system to decide what
to do.</p>
<p>The other thing that could happen is that the divisor could be just
too small for the dividend and the quotient could require more than 16
bits in which to be expressed. When this overflow condition is
detected, the division is halted, the overflow (V) status register code
bit is set, and the instruction is concluded without overwriting either
of the original operands. Thus, following any divide instruction, you
should check the overflow bit and act accordingly.</p>
<p>For a number of reasons, there are no instructions to multiply two
32-bit numbers or to divide a 64-bit number by a 32-bit number. First,
the need for such instructions is very infrequent in most applications.
Second, there are no other facilities in the machine to handle 64-bit
quantities. Finally, because such instructions would take a lot of time
to execute, the MC68000 would occasionally take much longer to respond
to an interrupt -- a situation the designers did not want to create.</p>
<p>The multiply instructions take fewer than 70 clock cycles to execute
using register operands, and the divide instructions require fewer than
140 clock cycles for an unsigned operation (158 cycles for a signed
operation); however, different combinations of 1s and 0s in the
operands can make these operations take less than these times to
execute. A short MC68000 routine that performs a 32-bit by 32-bit
multiplication is shown in listing 1. It executes in about 60
microseconds, which is less time than that taken by the dedicated
instruction that does the same thing in the Z8000.</p>
<hr>
<p><b>Listing 1:</b> <i>A short MC68000 assembly-language routine to multiply two 32-bit numbers.</i></p>
<pre>     Input:  register D0 contains 32-bit multiplicand
             register D1 contains 32-bit multiplier

     Output: registers D0 and D1 contain the 64-bit result,
              with the most significant byte in D0


         SUBQ    #4,A7            initialize product area
         CLR.L   -(A7)
         MOVE.L  D0,-(A7)         save copy of multiplicand

         MULU    D1,D0            multiply low-order parts
         MOVE.L  D0,8(A7)

         MOVE.W  (A7),D0          high-order multiplicand
         MULU    D1,D0             times low-order multiplier
         ADD.L   D0,6(A7)

         SWAP    D1               now use high-order multiplier
         MOVE.W  2(A7),D0         low-order multiplicand
         MULU    D1,D0             times high-order multiplier
         ADD.L   D0,6(A7)
         BCC     MUL32A           carry into high-order
         ADDQ.W  #1,4(A7)         word of product

 MUL32A  MOVE.L  (A7)+,D0         high-order multiplicand
         SWAP    D0
         MULU    D1,D0             times high-order multiplier
         ADD.L   (A7)+,D0
         ADDQ    #4,A7
         MOVE.L  (A7)+,D1         load low-order product</pre>
<hr>
<h3>Binary-Coded Decimal Arithmetic</h3>
<p>The final type of arithmetic instructions handles decimal digits.
The most common form of human-interface data comes as binary-coded
decimal or BCD data. This method of encoding numeric information as a
string of bits stores each decimal digit of the number as a 4-bit
binary number. Numbers are easily encoded into BCD form; once inside
the computer, they are easily printable in human-readable form (much
more so than numbers encoded in signed floating-point binary form).
Because the BCD format is so useful, most microprocessors include
instructions that operate on BCD numbers. To allow these BCD types of
data to be manipulated, the MC68000 has three instructions that add
(ABCD), subtract (SBCD), and negate (NBCD) packed digits. Each of these
instructions works on two BCD digits packed into a byte.</p>
<p>Because BCD numbers may be many digits wide, the BCD instructions
work as multiple-precision operations, which means they have the
characteristics of the other multiple-precision instructions. The
operands can be in data registers or in memory (in which case, they are
operated on using the predecrement addressing mode). The value of the X
status register code bit is included in the BCD operations, and the Z
status register bit is handled so that it properly reflects the state
of the entire result, not just the final portion.</p>
<p>Once again, the best thing about these instructions is the
simplicity with which they operate, especially when compared with the
often mysterious code a programmer had to write to do BCD arithmetic on
most older microprocessors. A glance at MC68000 code performing BCD
functions (see figure 4) shows how simple such code is. Here, two
6-digit numbers need to be added. While a short loop might make the
routine more generally useful, inline code is fastest and illustrates
the point best. First, we must load the two address registers to be
used as memory pointers with the correct values. The next instruction
(SUB D1,D1) is a quick way of both setting the Z bit and clearing the X
bit, though a MOVE #$04,CCR would do virtually the same thing.</p>
<hr>
<p><b>Figure 4:</b> <i>An example of multiple-precision binany-coded
decimal (BCD) arithmetic. Because the predecrement addressing mode used
("ABCD -(A1),-(A2)") decrements the register pointers before performing
the BCD addition, registers A1 and A2 must be loaded with a value that
points to the byte immediately after the least significant byte of the
number to be worked on.</i></p>

<pre> X    =  X   X   X   X   X   X        ADDRESS        MEMORY
  BCD     5   4   3   2   1   0       (HEXADECIMAL)  (ORGANIZED
                                                     AS WORDS)
 Y    =  Y   Y   Y   Y   Y   Y
  BCD     5   4   3   2   1   0                     |-------------|
                                                 FE |       X  X  |
                                                    |        5  4 |
                                                    |-------------|
                                                100 | X  X  X  X  |
                                                    |  3  2  1  0 |
                                                    |-------------|
                                                102 |             |
                                                    |             |
                                                    |-------------|
                                                    ~             ~
                                                    ~             ~
                                                    |-------------|
                                                1FE |       Y  Y  |
                                                    |        5  4 |
                                                    |-------------|
                                                200 | Y  Y  Y  Y  |
                                                    |  3  2  1  0 |
                                                    |-------------|
                                                202 |             |
                                                    |             |
                                                    |-------------|
                                                    |             |



 CODE TO ADD X    TO Y
              BCD     BCD

   MOVE.L #$102,A1     LOAD ADDRESS JUST PAST X IN A1
   MOVE.L #$202,A2     LOAD ADDRESS JUST PAST Y IN A2
   SUB    D1,D1        CLEAR X STATUS BIT AND SET Z STATUS BIT
   ABCD   -(A1),-(A2)  BCD ADDITION OF BOTTOM TWO DIGITS
   ABCD   -(A1),-(A2)  BCD ADDITION OF MIDDLE TWO DIGITS
   ABCD   -(A1),-(A2)  BCD ADDITION OF TOP TWO DIGITS</pre>
<hr>
<p>The three ABCD (add binary-coded-decimal) instructions begin at the
least significant two digits and move toward the most significant; this
must be done to get accurate results from use of the extend bit. The
result replaces the BCD number pointed to by A2; when the routine has
finished, A2 points to the first byte of the BCD result (which is
stored in order of most to least significant digit). Similar
subtraction and negation operations can be built in the same way.</p>
<h3>Logic Instructions</h3>
<p>The MC68000 logic instructions are simple but powerful. The AND, OR,
exclusive-or (EOR), and NOT instructions, like the arithmetic
instructions, allow 8-, 16-, and 32-bit quantities in data registers or
in memory to be operated on with any data register or an immediate
constant, or to be inverted. These instructions are just as fast as the
arithmetic instructions. Additionally, ANDI, ORI, and EORI instructions
are used to clear, set, and toggle individual status register code bits.</p>
<p>A serial shifter in the MC68000 can be moved any number of bits to
allow for shifting of 8-, 16-, and 32-bit data. The
arithmetic-shift-right instruction (ASR) shifts the least significant
bit to the X and C status bits while duplicating the most significant
bit before moving it to the right. In the arithmetic shift left (ASL),
the logical shift right (LSR), and the logical shift left (LSL), the
bit shifted out of the data area goes into the X and C bits, while the
bit into which no bit is being shifted is filled with a 0.</p>
<p>The rotate instructions shift bits around in a circular manner so
that bits shifted out of one end of an operand are shifted in the other
end, with the bit being shifted out of the data area also being copied
into the C status register code bit and, optionally, the X bit. The
rotate instructions are rotate right and rotate left (ROR and ROL); the
ROXR and ROXL instructions are used when you want to update both the X
and C bits.</p>
<p>One single shift or rotate instruction can move register data as
many as 31 bit positions in the selected direction. You can specify
this count value either statically (as a value between 1 and 8 encoded
into the instruction op code) when the instruction is written or
dynamically (as a value between 0 and 63 stored in a specified data
register) when the instruction is executed. For simplicity, memory
operands to be shifted or rotated are limited to displacements of 1 bit
and operations on word-sized data only. Table 4 illustrates some shift
and rotate instructions, their timing, and their effects.</p>
<hr>
<p><b>Table 4:</b> <i>Examples of shift and rotate instructions and their effect on registers and memory.</i></p>
<pre>                                                                     Status
Status Register                                                     Register
Instruction        Register                                          Codes
----------------------------------------------------------------------------
                                                                     C  X  V
----------------------------------------------------------------------------
ASR.B #3,D3        (D3 before) 10111010 01011111 01100101 10101100   x  x  x
(12 clock cycles)  (D3 after)  10111010 01011111 01100101 11110101   1  1  0
----------------------------------------------------------------------------
ASL.L #5,D1        (D1 before) 11101100 10100010 11011101 00101111   x  x  x
(18 clock cycles)  (D1 after)  10010100 01011011 10100101 11100000   1  1  1
----------------------------------------------------------------------------
LSL.W D5,D7        (D5 before) 00101000 10001100 11101001 00101001   x  x  x
                   (D7 before) 10111010 01011111 01100101 00010101   x  x  x
(24 clock cycles)  (D7 after)  10111010 01011111 00101010 00000000   0  0  0
----------------------------------------------------------------------------
ROL.L D2,D1        (D2 before) 01100101 00101010 10111110 01110100   x  x  x
                   (D1 before) 10010101 00101000 01000101 10010100   x  x  x
(48 clock cycles)  (D1 after)  01011001 01001001 01010010 10000100   0  x  0
----------------------------------------------------------------------------
ROXR.W #4,D6       (D6 before) 10111010 01011111 01100101 00010101   x  P  x
(14 clock cycles)  (D6 after)  10111010 01011111 101P0110 01010001   0  0  0
----------------------------------------------------------------------------
ROR $A0000           (word A0000 before)   10011100 10101001         x  x  x
                     (word A0000 after)    11001110 01010100         1  x  0</pre>
<p>Notes:</p>
<ol>
<li>An "x" status-register bit may represent either a 0 or 1 value.
</li><li>Notice that in the LSL.W and ROL.L examples the bottom siz
bits of the source operand (D5 and D2, respectively) are used as the
number of bits to be shifted or rotated.
</li><li>The "P" status-register bit in the "ROXR.W #4,D6" example is
specially marked to show that it is shifted into the body of the D6
register as a result of the ROXR.W instruction. Note that .W causes
only the bottom 16 bits of the register to be rotated.
</li></ol>
<hr>
<p>An important aspect of programming that until the MC68000 was quite
limited is that of individual bit manipulation, the ability to single
out bits of memory, test them, set them, and clear them. Such
operations are useful; in I/O, for instance, you frequently need to
sense the state of a single input line, drive a particular output line
high, or turn a servo-mechanism off. These operations involve only a
single bit associated with a latch, peripheral, or memory location.</p>
<p>In the past, most of us have done the best we could by executing
AND, OR, and EOR instructions to the desired location. But the
difficulty with these operations is their crudeness. Sure, they allow
us to change more than 1 bit at a time, but it turns out that much more
secure code can be written when single events or conditions affect
single outputs. Also, because it is impossible to sense the state of
more than one input at a time, nothing is gained by the ability of such
instructions to work on multiple bits.</p>
<p>Four powerful MC68000 instructions make all bit-manipulation
functions far simpler. They are the bit test (BTST), bit test and set
(BSET), bit test and clear (BCLR), and bit test and change (BCHG)
instructions. How will you specify the target bit? The MC68000 uses two
methods, similar to those used for shift and rotate instructions.
Either a data register or a series of bits in the bit-instruction op
code names the bit to be affected; in this case, however, the bit
number can be from 0 to 31 if a register is affected, or from 0 to 7 if
the area affected is a memory location. (In the MC68000, bits in memory
are identified by the bit number of the byte in which they reside.)</p>
<p>With true bit-manipulation instructions, not crude logic
instructions, bit-manipulation operations -- sensing the state of
inputs, driving outputs, setting register bits, setting attribute bits,
transposing bit matrices, or just building special data types -- are
straightforward tasks, not the chores they usually are with other
microprocessors. The MC68000 makes it very easy to specify precisely
the bit to be changed.</p>
<h3>Conclusions</h3>
<p>The computation and data-movement instructions that perform the
major work in any MC68000 program are numerous, comprehensive, and,
perhaps most important, straightforward and easy to use. The versatile
MOVE instruction on the MC68000 replaces a confusing variety of
data-movement instructions on other microprocessors. Flexible add,
subtract, compare, negate, multiply, and divide instructions operate on
any register, with constants, on stacks, and in memory using any
addressing mode. For digital data rather than binary data, pairs of BCD
numbers can be added, subtracted, and negated. The common logic
operations of AND, OR, exclusive-or, and NOT can similarly operate on
data registers and constants, and in memory.</p>
<p>When data needs to be shifted about, it can be arithmetic-shifted,.
logic-shifted, or rotated left or right. It can also be shifted or
rotated multiple bit positions, with the count of the movement either
predetermined and constant, or variable and dependent upon other data.</p>
<p>Individual bits in data or I/O can be separately tested to determine
their state; they can also be set, reset, or toggled. The bit to be
worked on can be chosen either when the instruction is written or,
based on other data, when it is run.</p>
<p>All the above instructions can operate on 8-, 16-, or 32-bit data,
with a uniform yet flexible set of addressing modes. This combination
of good instruction set design, computational power, and ease of use
make the MC68000 microprocessor an excellent one for assembly-language
programming. Next month, I'll discuss program-control instructions and
several advanced instruction groups.</p>
<hr>
<p><b>About the Author</b><br>Thomas Starnes is an electrical engineer
who has spent the last five years helping to plan the direction of the
MC68000 family of processor products for Motorola.</p>
</body></html>